#include <string.h>

#include "program.h"
#include "base64.h"

program::program():
	buffer_(NULL),
	size_(0),
	offs_(0),
	last_offs_(0),
	eof_(false)
{
}

program::~program()
{
  if (buffer_)
	delete buffer_;
}
	
bool program::init_from_buffer(const char *_buffer, size_t _size)
{
  if (buffer_)
  {
	delete buffer_;
	buffer_ = NULL;
  }  
  
  buffer_ = (char*)malloc(_size);
  
  if (buffer_ == NULL)
	return false;
	
  size_ = _size;	
	
  memcpy(buffer_, _buffer, _size);

  return true;
}

bool program::init_from_string(const std::string &_buffer)
{
  return init_from_buffer(_buffer.c_str(), _buffer.size());
}

bool program::init_from_base64(const std::string &_buffer)
{
	std::string dst;
	
    dst.reserve (_buffer.length() * 3 / 4);
    std::back_insert_iterator<std::string> out_iter (dst);

    base64::decoder base64;
    base64.decode(_buffer.begin(), _buffer.end(), out_iter);
    
    return init_from_string(dst);
}

void program::reset()
{
  eof_ = false;
  offs_ = 0;
}

bool program::eof()
{
  return eof_;
}

unsigned int program::get_offs()
{
	return offs_;
}

void program::get_next_chunk(char *_buffer, size_t _size, size_t &_real_size, bool _repeat)
{
  size_t copy_size  = 0;
  
  if (_repeat)
  {
	  offs_ = last_offs_;
  }
  
  if ((offs_ + _size) >= size_)
  {
	copy_size = size_ - offs_;
	eof_ = true;
  }
  else
  {
	copy_size = _size;
	eof_ = false;
  }
  
  memmove(_buffer, buffer_ + offs_, copy_size);
  
  last_offs_ = offs_;
  
  offs_ += copy_size;
  
  _real_size = copy_size;
}
